package process

import (
	models "MessageSendService/app/common/models"
	"fmt"
)

var processController *ProcessController

type processCode int

// ProcessTemplate 一条责任链实际上就是一个list，把BusinessProcess串联起来
type ProcessTemplate struct {
	list []BusinessProcess
}

func GetProcessController() *ProcessController {
	return processController
}

// ProcessController 存储了各种业务的责任链，比如发送消息，撤回消息
type ProcessController struct {
	templateMap map[int]ProcessTemplate
}

func NewProcessController() *ProcessController {
	return &ProcessController{
		templateMap: make(map[int]ProcessTemplate),
	}
}

func (p *ProcessController) AddProcess(code int, process BusinessProcess) {
	if _, ok := p.templateMap[code]; !ok {
		p.templateMap[code] = ProcessTemplate{
			list: make([]BusinessProcess, 0),
		}
	}

	temp := p.templateMap[code]
	temp.list = append(temp.list, process)
	p.templateMap[code] = temp
	//  p.templateMap[code].list = append(p.templateMap[code].list, process)  上面用这种方式为啥不行呢？因为list是一个副本，无法直接修改
}

// Process 执行某一个责任链
func (p *ProcessController) ProcessExecute(ctx *ProcessContext) error {
	//1.根据code找到对应的链
	temp, ok := p.templateMap[ctx.Code]
	if !ok {
		return fmt.Errorf("找不到对应执行的责任链")
	}
	//2.执行该链下list的所有操作
	for _, process := range temp.list {
		err := process.Process(ctx)
		if err != nil {
			return err
		}
		if ctx.NeedBreak {
			return nil
		}
	}
	return nil
}

type BusinessProcess interface {
	// Process 指针类型才能修改值并且传递context
	Process(ctx *ProcessContext) error
}

// ProcessModel
// 责任链真正存储数据的模型
type ProcessModel struct {
	// 消息模版id
	MessageTemplateId int64 `json:"message_template_id"`
	//消息参数
	MessageParam []models.MessageParam `json:"message_param"`
	// 存储封装消息的消息结构体           //责任链执行过程中会根据MessageParmId和MessageParam把这个字段填上，每条消息对应一个models.TaskInfo
	TaskInfo []models.TaskInfo
}

type ProcessContext struct {
	Code         int          // 当前责任链的code
	ProcessModel ProcessModel // 责任链数据模型
	NeedBreak    bool         // 是否需要结束执行该责任链
}
